#include "cc_stdlib.h"
#include "cc_ctype.h"
#include "cc_buffer.h"
#include "cc_malloc.h"
#include "cc_memory.h"
#include "cc_for.h"
#include <stdio.h>
#include <windows.h>

#pragma warning(disable:4996)

void __cdecl cc_swab(
	char *src,
	char *dest,
	int bytes
	)
{
	char temp;
	while(bytes--)
	{
		temp = *(src + bytes - 1);
		*(dest + bytes - 1) = temp;
		*(src + bytes - 1) = *(dest + bytes - 1);
	}
}

int __cdecl cc_atoi(const char *str)
{
	int sign;
	int num;

	// skip the blank characters
	while(isspace(*str))
	{
		++str;
	}

	sign = 1;
	// get the positive or neg symbol
	switch(*str)
	{
	case '-': sign = -1;
	case '+': ++str;
	}

	num = 0;
	// get the real num , one char by one char
	while(cc_isdigit(*str))
	{
		num = num * 10 + *str++ - '0';
	}

	return (sign * num);
}

long __cdecl cc_atol(const char *str)
{
	return (long)cc_atoi(str);
}

double __cdecl cc_atof(const char *str)
{
	double result = 0;
	int meetDot = 0;		// whether meet character '.'
	int meetE = 0;			// whether meet character 'e' or 'E'
	int numCountAfterDot = 1;		// the count of numbers after dot '.'
	int numAfterE = 0;		// the number after character 'e' or 'E':  1.29877e123, the final numAfterE is 123

	cc_skipBlankCharacters(&str);

	while(*str)
	{
		switch(*str)
		{
		case '.':
			{
				meetDot = 1;
				++str;
			}
			continue;

		case 'e':
		case 'E':
			{
				meetE = 1;
				++str;
			}
			continue;

		default:
			{
				if(!meetDot)
				{
					if(!meetE)
						result = result * 10 + (*str - '0');
					else
						numAfterE = numAfterE * 10 + (*str - '0');
				}
				else
				{
					if(!meetE)
					{
						result += (1.0 / cc_integral_power(10, numCountAfterDot)) * (*str - '0');
						++numCountAfterDot;
					}
					else
						numAfterE = numAfterE * 10 + (*str - '0');
				}

				++str;
			}
			continue;
		}
	}
	return result * cc_integral_power(10, numAfterE);
}

char * __cdecl cc_itoa(int n)
{
	return cc_itoa_helper(n, 10);
}

char * __cdecl cc_itoa_helper(
	int n, 
	unsigned int radix
	)
{
	char nChar[SMALL_BUFFER + 1] = {0};
	int len = 0;
	char *temp;
	char *tempCp;

	if(radix == 0 || radix == 1 || radix > 16)	// can't convert 0, 1 or over 16th radix
		return NULL;

	temp = (char *)cc_malloc(SMALL_BUFFER + 1);
	tempCp = temp;
	if(!tempCp)
		return NULL;

	cc_memset(tempCp, 0, SMALL_BUFFER + 1);

	if(n < 0)
		*tempCp++ = '-';

	// fill the nChar arr, if n == 123, then nChar is "321".
	while(n)
	{
		int m = n % radix;
		nChar[len++] = cc_getCharFromHexValue(m);

		n /= radix;
	}

	while(len > 0)
		*tempCp++ = nChar[--len];

	return temp;
}

char cc_getCharFromHexValue( 
	int n 
	)
{
	if(n < 10)
		return (n + '0');
	else
		return (n - 10 + 'A');
}

void __cdecl cc_exit( 
	int status 
	)
{
	ExitProcess(status);
}

// a simple abort
void __cdecl cc_abort(
	void
	)
{
	cc_exit(3);
}

void __cdecl sleep( 
	int miliseconds 
	)
{
	Sleep(miliseconds);
}

void __cdecl ding( 
	int dingTimes 
	)
{
	int i = 0;
	for(; i < dingTimes; ++i)
	{
		printf("\a");
	}
}

/*
void __cdecl cc_srand(size_t seed)
{
	_getptd()->_holdrand = (unsigned long)seed;
}
*/

